home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 52
/
Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso
/
Aminet
/
misc
/
emu
/
Apex-src.lha
/
DISASM.XPL
< prev
next >
Wrap
Text File
|
2001-09-30
|
21KB
|
966 lines
\DISASM.XPL APR-10-87
\68000/68881 Disassembler
\ by Loren Blaney
\
\REVISION HISTORY:
\DEC-26-85, Added 68881 instructions, L.B.
\MAR-03-86, Modified for 32-bit XPL, L.B.
\AUG-23-86, Fixed miscellaneous bugs, L.B.
\OCT-18-86, Modified for new compiler.
\APR-10-87, Changed string convention, fixed MUL and DIV, and PC relative
\ addresses.
\
\NOTES:
\The output is buffered (in LINBUF) and is divided into fields:
\ 1 2 3 4
\01234567890123456789012345678901234567890123456789
\ASCII PC HEX TEXT (MNEMONICS)
\AABBCCDDEE 00000000: 00001111222233334444 TEXT..........
\
\(Contrary to what Motorola claims, the 68000 is not very symmetrical.)
\WARNING:
\The size extensions are used haphazardly.
\The FDBcc instructions don't consistently display the target branch addr.
code
ABS=0, RAN=1, REM=2, RESERVE=3,
SWAP=4, EXTEND=5, RESTART=6, CHIN=7,
CHOUT=8, CRLF=9, INTIN=10, INTOUT=11,
TEXT=12, OPENI=13, OPENO=14, CLOSE=15,
ABORT=16 HEXIN=26, HEXOUT=27, SWAP_W=117,
EXT_L=118, GETKEY=125;
def TV=0, KB=0;
def TAB=$09, BEL=$07, CR=$0D, LF=$0A, ESC=$1B;
addr BASE; \Base address of PC (usually = 0)
int II, \Scratch
DEV, \Output device number
PC, \Program Counter
OP, \16-bit opcode
DSTREG, \3-bit destination register field of OP
DSTMODE, \3-bit destination mode field
SRCMODE, \3-bit source mode field
SRCREG, \3-bit source register
SIZE, \2-bit size field (0=B, 1=W, 2=L)
CC, \4-bit condition code field
CC1,CC2, \Condition code letters
BIT, \Table of bit positions
LINEPTR, \Pointer into LINEBUF
ASCPTR, \Pointer into ASCII field
HEXPTR, \Pointer into hex field
TXTPTR; \Pointer into text field
def LINEMAX=79; \Last byte of LINEBUF
addr LINEBUF, \Line buffer
HEXTBL, \Hex table
CCSTR; \String array containing all condition codes
\----------------------------------------------------------------------\
proc CHARO(CH); \Write char to line buffer
int CH;
begin
LINEBUF(LINEPTR):= CH;
if LINEPTR<LINEMAX then LINEPTR:= LINEPTR+1;
end; \CHARO
proc CHO(CH); \Write char to text field
int CH;
begin
LINEPTR:= TXTPTR;
CHARO(CH);
TXTPTR:= LINEPTR;
end; \CHO
proc CRO; \Write CR LF to text field
begin
CHO(CR);
end; \CRO
proc TXT(STR); \Write string to text field
addr STR;
int I;
begin
LINEPTR:= TXTPTR;
loop for I:= 0,32767 do
begin
if STR(I) = 0 then quit;
CHARO(STR(I));
end;
TXTPTR:= LINEPTR;
end; \TXT
proc NUMO(N); \Write signed, 16-bit decimal integer to text field
int N;
int I,X,ZEROFL,TENPWR;
begin
LINEPTR:= TXTPTR;
N:= EXT_L(N);
if N<0 then [N:= -N; CHARO(^-)];
\(Note that with 32-bit XPL, a 16-bit integer will never appear negative.)
TENPWR:= 10000;
ZEROFL:= 0;
for I:= 0,3 do
begin
X:= N/TENPWR;
N:= REM(0);
ZEROFL:= ZEROFL ! X;
if ZEROFL then CHARO(X+^0);
TENPWR:= TENPWR/10;
end;
CHARO(N+^0);
TXTPTR:= LINEPTR;
end; \NUMO
proc HEXB(N); \Write hex byte to line buffer
int N;
begin
CHARO(HEXTBL((N&$FF)/$10));
CHARO(HEXTBL(REM(0)));
end; \HEXB
proc HEXW(N); \Write hex word to line buffer
int N;
begin
HEXB(SWAP(N));
HEXB(N);
end; \HEXW
proc HEXO(N); \Write hex word to text field
int N;
begin
LINEPTR:= TXTPTR;
HEXW(N);
TXTPTR:= LINEPTR;
end; \HEXO
proc ASCO(N); \Write ASCII-dump char to line buffer
int N;
int CH;
begin
CH:= N&$7F;
if CH<$20 ! CH=$7F then CH:= ^.;
CHARO(CH);
end; \ASCO
proc DUMP(N); \Write hex- and ASCII-dump to line buffer
int N;
begin
LINEPTR:= HEXPTR;
HEXW(N);
HEXPTR:= LINEPTR;
LINEPTR:= ASCPTR;
ASCO(SWAP(N));
ASCO(N);
ASCPTR:= LINEPTR;
end; \DUMP
proc GETOP; \Get opcode at PC and bump PC
begin
\Note that the 6502 and the 68000 order high and low bytes differently.
OP:= SWAP(BASE(PC)) + BASE(PC+1);
DUMP(OP);
PC:= PC +2;
end; \GETOP
\----------------------------------------------------------------------\
proc D(REG); \Output data register
int REG;
begin
CHO(^D); NUMO(REG);
end; \D
proc A(REG); \Output address register
int REG;
begin
if REG=7 then TXT("SP")
else [CHO(^A); NUMO(REG)];
end; \A
proc DOMODE(MODE, REG); \Output effective address
int MODE, REG;
begin
case MODE of
$0: D(REG); \Dn
$1: A(REG); \An
$2: [CHO(^(); A(REG); CHO(^))]; \(An)
$3: [CHO(^(); A(REG); TXT(")+")]; \(An)+
$4: [TXT("-("); A(REG); CHO(^))]; \-(An)
$5: [GETOP; NUMO(OP); CHO(^(); A(REG); CHO(^))]; \d(An)
$6: [GETOP; NUMO(EXTEND(OP&$00FF)); \d(An,Xi)
CHO(^(); A(REG); CHO(^,);
CHO(if OP&$8000 then ^A else ^D); NUMO((OP&$7000)/$1000);
CHO(^.); CHO(if OP&$0800 then ^L else ^W); CHO(^))];
$7: case REG of
0: [GETOP; CHO(^$); HEXO(OP); TXT(".W")]; \Abs.W
1: [GETOP; CHO(^$); HEXO(OP); GETOP; HEXO(OP); TXT(".L")]; \Abs.L
2: [GETOP; CHO(^$); HEXO(SWAP_W(EXT_L(OP)+PC-2));
HEXO(OP+PC-2); TXT("(PC)")]; \d(PC)
3: [GETOP; CHO(^$); HEXO(PC-2+(EXTEND(OP&$00FF))); \d(PC,Xi)
TXT("(PC,");
CHO(if OP&$8000 then ^A else ^D); NUMO((OP&$7000)/$1000);
CHO(^.); CHO(if OP&$0800 then ^L else ^W); CHO(^))];
4: [TXT("#$"); \Imm
GETOP;
case SIZE of
0: HEXO(OP); \(not sign extended)
1: HEXO(OP);
2: [HEXO(OP); GETOP; HEXO(OP)]
other TXT("???")]
other TXT("???")
other;
end; \DOMODE
proc DST; \Destination effective address
begin
DOMODE(DSTMODE, DSTREG);
end; \DST
proc SRC; \Source effective address
begin
DOMODE(SRCMODE, SRCREG);
end; \SRC
proc SIZEXT; \Output size extension
begin
CHO(^.);
case SIZE of
0: CHO(^B);
1: CHO(^W);
2: CHO(^L)
other CHO(^?);
CHO(TAB);
end; \SIZEXT
func REVERSE(N); \Reverse the order of the bits in N
int N;
int I, M;
begin
M:= 0;
for I:= 0,15 do
if BIT(I) & N then M:= M ! BIT(15-I);
return M;
end; \REVERSE
proc SHOWREGS(MASK); \Show the registers defined by MASK
int MASK; \Order from MSB to LSB: A7-A0/D7-D0
int I, HIT, RUN, FIRST;
proc SREGS(MASK, R); \Show data or address registers
int MASK, R;
begin
HIT:= false;
RUN:= false;
for I:= 0,7 do
begin
if BIT(I) & MASK then \Bit is set
begin
if HIT then RUN:= true
else [if FIRST then FIRST:= false else CHO(^/);
CHO(R); NUMO(I); HIT:= true];
end
else begin \Bit is clear
if RUN then [CHO(^-); CHO(R); NUMO(I-1)];
HIT:= false;
RUN:= false;
end;
end;
if RUN then [CHO(^-); CHO(R); NUMO(7)];
end; \SREGS
begin \SHOWREGS
FIRST:= true;
SREGS(MASK, ^D);
SREGS(SWAP(MASK), ^A);
end; \SHOWREGS
proc MOVEMOP; \Generate a MOVEM instruction, e.g: MOVEM. D1-D7,64(A0)
begin
TXT("MOVEM");
SIZEXT;
GETOP;
SHOWREGS(if SRCMODE=4 then REVERSE(OP) else OP);
CHO(^,);
SRC;
end; \MOVEMOP
proc TWOOP; \Decoding for two operands
\This is correct for ADD & SUB, the most general case, other
\ operators should do their exceptions first.
begin
case DSTMODE of
$0: [TXT(".B "); SRC; CHO(^,); D(DSTREG)];
$1: [TXT(".W "); SRC; CHO(^,); D(DSTREG)];
$2: [TXT(".L "); SRC; CHO(^,); D(DSTREG)];
$3: [TXT("A.W "); SRC; CHO(^,); A(DSTREG)];
$4: [TXT(".B "); D(DSTREG); CHO(^,); SRC];
$5: [TXT(".W "); D(DSTREG); CHO(^,); SRC];
$6: [TXT(".L "); D(DSTREG); CHO(^,); SRC];
$7: [TXT("A.L "); SRC; CHO(^,); A(DSTREG)]
other;
end; \TWOOP
proc IMMOP; \Group $0000
proc IMM(STR);
addr STR;
begin
TXT(STR);
if SRCMODE=7 & SRCREG=4 then
begin
TXT(" #$"); GETOP; HEXO(OP);
if OP&$0040 then TXT(",SR") else TXT(",CCR");
end
else [SIZEXT; TXT("#$"); GETOP; HEXO(OP);
if SIZE=2 then [GETOP; HEXO(OP)]; \Long
CHO(^,); SRC];
end; \IMM
begin \IMMOP
if OP&$0100 then
begin
if SRCMODE=1 then
[TXT("MOVEP.");
case SIZE of
0: [TXT("W "); GETOP; NUMO(OP); CHO(^();
A(SRCREG); TXT("),"); D(DSTREG)];
1: [TXT("L "); GETOP; NUMO(OP); CHO(^();
A(SRCREG); TXT("),"); D(DSTREG)];
2: [TXT("W "); D(DSTREG); CHO(^,);
GETOP; NUMO(OP); CHO(^(); A(SRCREG); CHO(^))];
3: [TXT("L "); D(DSTREG); CHO(^,);
GETOP; NUMO(OP); CHO(^(); A(SRCREG); CHO(^))]
other;
]
else [case SIZE of \Dynamic bit ops
0: TXT("BTST");
1: TXT("BCHG");
2: TXT("BCLR");
3: TXT("BSET")
other;
SIZE:= 2; \Size = long only
TXT(" "); D(DSTREG); CHO(^,); SRC;
];
end
else begin
case DSTREG of
0: IMM("ORI");
1: IMM("ANDI");
2: IMM("SUBI");
3: IMM("ADDI");
4: [case SIZE of
0: TXT("BTST");
1: TXT("BCHG");
2: TXT("BCLR");
3: TXT("BSET")
other;
SIZE:= 0; \Size = byte only
TXT(" #"); GETOP; NUMO(OP&$007F); CHO(^,); SRC;
];
5: IMM("EORI");
6: IMM("CMPI");
7: [TXT("MOVES"); SIZEXT; CHO(^$); GETOP; HEXO(OP)]
other;
end;
end; \IMMOP
proc MOVEOP; \Generate a MOVE instruction ($1000, $2000, $3000)
begin
TXT("MOVE");
if DSTMODE=1 then CHO(^A);
SIZEXT;
SRC; CHO(^,); DST;
end; \MOVEOP
proc NEGXOP; \Group $4000
int SOP;
begin
case DSTMODE of
6: [SIZE:= 1; TXT("CHK "); SRC; CHO(^,); D(DSTREG)];
7: [TXT("LEA "); SRC; CHO(^,); A(DSTREG)]
other begin
case DSTREG of
0: if SIZE=3 then [SIZE:= 1; TXT("MOVE SR,"); SRC]
else [TXT("NEGX"); SIZEXT; SRC];
1: if SIZE=3 then [SIZE:= 1; TXT("MOVE CCR,"); SRC]
else [TXT("CLR"); SIZEXT; SRC];
2: if SIZE=3 then [SIZE:= 1; TXT("MOVE "); SRC; TXT(",CCR")]
else [TXT("NEG"); SIZEXT; SRC];
3: if SIZE=3 then [SIZE:= 1; TXT("MOVE "); SRC; TXT(",SR")]
else [TXT("NOT"); SIZEXT; SRC];
4: case DSTMODE of
0: [TXT("NBCD "); SRC];
1: if SRCMODE=0 then [TXT("SWAP "); D(SRCREG)]
else [TXT("PEA "); SRC];
2: if SRCMODE=0 then [TXT("EXT.W "); D(SRCREG)]
else [SIZE:= 1; MOVEMOP];
3: if SRCMODE=0 then [TXT("EXT.L "); D(SRCREG)]
else [SIZE:= 2; MOVEMOP]
other TXT("???");
5: if SIZE=3 then
begin
if SRCMODE=7 then TXT("ILLEGAL")
else [SIZE:= 0; TXT("TAS "); SRC];
end
else [TXT("TST"); SIZEXT; SRC];
6: [TXT("MOVEM."); CHO(if OP&$0040 then ^L else ^W); CHO(TAB);
GETOP; SOP:= OP; SRC; CHO(^,); SHOWREGS(SOP)];
\(Register bits won't need reversing because predecrement is not allowed)
7: begin
case DSTMODE of
1: begin
case SRCMODE of
0,1: [TXT("TRAP #"); NUMO(OP&$000F)];
2: [TXT("LINK "); A(SRCREG); TXT(",#");
GETOP; NUMO(OP)];
3: [TXT("UNLK "); A(SRCREG)];
4: [TXT("MOVE "); A(SRCREG); TXT(",USP")];
5: [TXT("MOVE USP,"); A(SRCREG)];
6: begin
case SRCREG of
0: TXT("RESET");
1: TXT("NOP");
2: TXT("STOP");
3: [TXT("RTE"); CRO];
4: [TXT("RTD"); CRO];
5: [TXT("RTS"); CRO];
6: TXT("TRAPV");
7: [TXT("RTR"); CRO]
other;
end;
7: TXT("MOVEC")
other;
end;
2: [TXT("JSR "); SRC];
3: [TXT("JMP "); SRC; CRO]
other TXT("???");
end
other;
end;
end; \NEGXOP
proc ADDQOP; \Group $5000: ADDQ, SCC, DBCC, SUBQ
proc QUICK(STR);
addr STR;
begin
TXT(STR);
SIZEXT;
CHO(^#); NUMO(if DSTREG=0 then 8 else DSTREG); CHO(^,);
SRC;
end; \QUICK
begin \ADDQOP
case DSTMODE of
$0,$1,$2: QUICK("ADDQ");
$3,$7: if SRCMODE=1 then
begin
TXT("DB"); CHO(CC1); CHO(CC2);
CHO(TAB); D(SRCREG);
CHO(^,); GETOP; CHO(^$);
HEXO(SWAP_W(EXT_L(OP)+PC-2));
HEXO(OP+PC-2);
end
else begin
CHO(^S); CHO(CC1); CHO(CC2);
CHO(TAB); SRC;
end;
$4,$5,$6: QUICK("SUBQ")
other;
end; \ADDQOP
proc BRAOP; \Generate branch instructions (group $6000)
int DISP;
begin
case CC of
0: [TXT("BRA")]; \Do the exceptions first
1: [TXT("BSR")]
other [CHO(^B); CHO(CC1); CHO(CC2)];
DISP:= OP&$00FF;
if DISP=0 then [TXT(".L $"); GETOP; HEXO(SWAP_W(EXT_L(OP)+PC-2)); HEXO(OP+PC-2)]
else [TXT(".S $"); HEXO(SWAP_W(EXT_L(EXTEND(DISP))+PC)); HEXO(EXTEND(DISP)+PC)];
if CC=0 then CRO;
end; \BRAOP
proc OROP; \Group $8000
begin
if DSTMODE=4 & SRCMODE=0 then
[TXT("SBCD "); D(SRCREG); CHO(^,); D(DSTREG)]
else if DSTMODE=4 & SRCMODE=1 then
[TXT("SBCD "); TXT("-("); A(SRCREG);
TXT("),-("); A(DSTREG); CHO(^))]
else case DSTMODE of
3: [TXT("DIVU"); CHO(TAB); SRC; CHO(^,); D(DSTREG)];
7: [TXT("DIVS"); CHO(TAB); SRC; CHO(^,); D(DSTREG)]
other [TXT("OR"); TWOOP];
end; \OROP
proc SUBOP; \Group $9000
begin
TXT("SUB");
TWOOP;
end; \SUBOP
proc CMPOP; \Group $B000
begin
case DSTMODE of 4,5,6:
if SRCMODE=1 then
[TXT("CMPM"); SIZEXT; CHO(^();
A(SRCREG); TXT(")+,("); A(DSTREG); TXT(")+")]
else [TXT("EOR"); TWOOP]
other [TXT("CMP"); TWOOP];
end; \CMPOP
proc ANDOP; \Group $C000
begin
case of
DSTMODE=5 & SRCMODE=0: [TXT("EXG "); D(SRCREG);
CHO(^,); D(DSTREG)];
DSTMODE=5 & SRCMODE=1: [TXT("EXG "); A(SRCREG);
CHO(^,); A(DSTREG)];
DSTMODE=6 & SRCMODE=1: [TXT("EXG "); A(SRCREG);
CHO(^,); D(DSTREG)];
DSTMODE=4 & (SRCMODE&6)=0: [TXT("ABCD"); TWOOP]
other case DSTMODE of \ABCD,
3: [TXT("MULU"); CHO(TAB); SRC; CHO(^,); D(DSTREG)];
7: [TXT("MULS"); CHO(TAB); SRC; CHO(^,); D(DSTREG)]
other [TXT("AND"); TWOOP];
end; \ANDOP
proc ADDOP; \Group $D000
begin
TXT("ADD");
TWOOP;
end; \ADDOP
proc SHIFTOP; \Group $E000
proc NAME(TYPE);
int TYPE;
begin
case TYPE of
0: TXT("AS");
1: TXT("LS");
2: TXT("ROX");
3: TXT("RO")
other;
CHO(if OP&$0100 then ^L else ^R);
end; \NAME
begin
case SIZE of
0,1,2: begin
NAME((OP&$0018)/$8);
SIZEXT;
if OP&$0020 then \I/R field
[D(DSTREG)]
else [CHO(^#); NUMO(if DSTREG=0 then 8 else DSTREG)];
CHO(^,);
D(SRCREG);
end;
3: begin
SIZE:= 1; \Shift memory, size = word only
NAME((OP&$0300)/$200);
CHO(TAB);
SRC;
end
other;
end; \SHIFTOP
\----------------------------------------------------------------------\
proc FLINE; \Group $F000, 68881 instructions
int K, FDSTREG, FSRCREG;
proc FMT(F); \Output the field specifier
int F;
addr STR;
begin
CHO(^.);
STR:= "LSXPWDBP ";
CHO(STR(F));
end; \FMT
proc FP(REG); \Output the floating-point register
int REG;
begin
TXT("FP"); NUMO(REG);
end; \FP
proc DOFOP(STR); \Disassemble common floating-point opcodes
addr STR;
int FSRCREG, FDSTREG;
begin
TXT(STR);
FSRCREG:= (OP & $1C00) /$400;
FDSTREG:= (OP & $0380) /$80;
if OP & $4000 then \Test R/M bit
begin \FABS<fmt> <ea>,FPn
FMT(FSRCREG); CHO(TAB); SRC; CHO(^,); FP(FDSTREG);
end
else begin \The operation is register to register
TXT(".X "); FP(FSRCREG);
if FSRCREG#FDSTREG then \FABS.X FPm,FPn
[CHO(^,); FP(FDSTREG)];
end;
end; \DOFOP;
proc DOMOVCR; \FMOVECR #$xx,FPn
begin
TXT("FMOVECR #$");
HEXO(OP&$7F);
CHO(^,);
FP((OP&$0380)/$80);
end; \DOMOVCR
proc DOFCC; \Output the condition code
int I, FCC;
begin
I:= OP & $3F;
if I<=$20 then
begin
FCC:= ["F", "EQ", "OGT", "OGE", "OLT", "OLE", "OGL", "OR",
"UN", "UEQ", "UGT", "UGE", "ULT", "ULE", "NE", "T",
"SF", "SEQ", "GT", "GE", "LT", "LE", "GL", "GLE",
"NGLE", "NGL", "NLE", "NLT", "NGE", "NGT", "SNE", "ST"];
TXT(FCC(I));
end
else CHO(^?); \Undefined
end; \DOFCC
begin \FLINE
case DSTMODE of \Bits: 8, 7, & 6
0: begin
GETOP;
case OP & $E000 of
$0000,$4000:
begin
case OP & $7F of
$00: if (OP&$5C00) = $5C00 then DOMOVCR
else DOFOP("FMOVE"); \Memory-to-register operation
$01: DOFOP("FINT");
$02: DOFOP("FSINH");
$03: DOFOP("FINTRZ");
$04: DOFOP("FSQRT");
$06: DOFOP("FLOGNP1");
$08: DOFOP("FETOXM1");
$09: DOFOP("FTANH");
$0A: DOFOP("FATAN");
$0C: DOFOP("FASIN");
$0D: DOFOP("FATANH");
$0E: DOFOP("FSIN");
$0F: DOFOP("FTAN");
$10: DOFOP("FETOX");
$11: DOFOP("FTWOTOX");
$12: DOFOP("FTENTOX");
$14: DOFOP("FLOGN");
$15: DOFOP("FLOG10");
$16: DOFOP("FLOG2");
$18: DOFOP("FABS");
$19: DOFOP("FCOSH");
$1A: DOFOP("FNEG");
$1C: DOFOP("FACOS");
$1D: DOFOP("FCOS");
$1E: DOFOP("FGETEXP");
$1F: DOFOP("FGETMAN");
\In the following FPm should not = FPn
$20: DOFOP("FDIV");
$21: DOFOP("FMOD");
$22: DOFOP("FADD");
$23: DOFOP("FMUL");
$24: DOFOP("FSGLDIV");
$25: DOFOP("FREM");
$26: DOFOP("FSCALE");
$27: DOFOP("FSGLMUL");
$28: DOFOP("FSUB");
$38: DOFOP("FCMP");
$3A: DOFOP("FTST") \FPm is not used and it should be = 0
other begin
\WARNING! order is backwards: SIN, COS
if (OP&$0078) = $30 then
[DOFOP("FSINCOS"); CHO(^:); FP(OP&$0007)];
end;
end;
$2000: TXT("???");
$6000: begin \FMOVE.<fmt> FPn,<ea>
TXT("FMOVE");
FDSTREG:= (OP & $1C00) /$400;
FSRCREG:= (OP & $0380) /$80;
FMT(FDSTREG); CHO(TAB); FP(FSRCREG); CHO(^,); SRC;
if FDSTREG=3 then
[TXT("{#"); K:= OP&$007F;
if K>=$40 then K:= K-$80;
NUMO(K); CHO(^})];
if FDSTREG=7 then
[TXT("{D"); NUMO((OP&$70) /$10); CHO(^})];
end;
$8000: begin \FMOVE(M) <ea>,FPcr
TXT("FMOVE(M) ");
SRC;
FDSTREG:= (OP & $1C00) /$400;
if FDSTREG&1 then TXT(",FPCR");
if FDSTREG&2 then TXT(",FPSR");
if FDSTREG&4 then TXT(",FPIAR")
end;
$A000: begin \FMOVE(M) FPcr,<ea>
TXT("FMOVE(M) ");
FSRCREG:= (OP & $1C00) /$400;
if FSRCREG&1 then TXT("FPCR,");
if FSRCREG&2 then TXT("FPSR,");
if FSRCREG&4 then TXT("FPIAR,");
SRC;
end;
$C000: begin \FMOVEM <ea>,FPn
TXT("FMOVEM ");
SRC;
CHO(^,);
GETOP; \WARNING! inaccurate
SHOWREGS( SWAP(REVERSE(OP&$00FF)) );
end;
$E000: begin \FMOVEM FPn,<ea>
TXT("FMOVEM ");
GETOP; \WARNING! inaccurate
SHOWREGS( SWAP(REVERSE(OP&$00FF)) );
CHO(^,);
SRC;
end
other;
end;
1: begin \FDBcc, FScc, & FTRAPcc
case SRCMODE of
1: begin \FDBcc Dn,<label>
TXT("FDB");
GETOP;
DOFCC;
CHO(TAB);
D(SRCREG);
GETOP;
HEXO(OP+PC-4);
end;
7: begin \FTRAPcc
TXT("FTRAP"); \(do exceptions first)
GETOP;
DOFCC;
case SRCREG of \Mode field
2: [TXT(".W #$"); GETOP; HEXO(OP)];
3: [TXT(".L #$"); GETOP; HEXO(OP); GETOP; HEXO(OP)]
other [TXT("FS"); GETOP; DOFCC; CHO(TAB); SRC];
end
other begin \FScc <ea>
TXT("FS"); GETOP; DOFCC; CHO(TAB); SRC;
end;
end;
2: begin \FBcc & FNOP (16 bits)
if (OP & $3F) = 0 then TXT("FNOP")
else begin
TXT("FB"); DOFCC; TXT(".W $");
GETOP;
HEXO(OP+PC-2); \Show the target address
end;
end;
3: begin \FBcc (32 bits)
TXT("FB"); DOFCC; TXT(".L $");
GETOP;
HEXO(OP); \Show the displacement
GETOP;
HEXO(OP);
end;
4: begin \FSAVE
TXT("FSAVE ");
SRC;
end;
5: begin \FRESTORE
TXT("FRESTORE ");
SRC;
end
other TXT("???");
end; \FLINE
\----------------------------------------------------------------------\
proc LOOKUP;
begin
\Chop the opcode into fields:
DSTREG:= (OP&$0E00) /$200;
DSTMODE:= (OP&$01C0) /$40;
SRCMODE:= (OP&$0038) /$8;
SRCREG:= (OP&$0007);
CC:= (OP&$0F00) /$100;
CCSTR:= "T F HILSCCCSNEEQVCVSPLMIGELTGTLE ";
CC1:= CCSTR(CC*2);
CC2:= CCSTR(CC*2 +1);
SIZE:= (OP&$00C0) /$40;
case OP & $F000 of
$0000: IMMOP; \ORI, MOVEP, AND, SUBI, ADDI, EORI, CMPI, MOVES
$1000: [SIZE:= 0; MOVEOP]; \MOVE.B
$2000: [SIZE:= 2; MOVEOP]; \MOVE.L
$3000: [SIZE:= 1; MOVEOP]; \MOVE.W
$4000: NEGXOP; \NEGX, MOVE SR, CHK, LEA, CLR, ... JMP
$5000: ADDQOP; \ADDQ, SCC, DBCC, SUBQ
$6000: BRAOP;
$7000: [TXT("MOVEQ #"); NUMO(EXTEND(OP & $FF)); CHO(^,);
D(DSTREG)]; \MOVEQ
$8000: OROP; \OR, DIV, SBCD
$9000: SUBOP; \SUB
$A000: TXT("1010 EMULATOR"); \Line 1010 emulator
$B000: CMPOP; \CMP, EOR
$C000: ANDOP; \AND, MUL ABCD, EXG
$D000: ADDOP; \ADD
$E000: SHIFTOP; \Shift/rotate
$F000: FLINE \68881 line $F emulator
other;
end; \LOOKUP
\----------------------------------------------------------------------\
begin \MAIN
LINEBUF:= RESERVE(LINEMAX+1);
HEXTBL:= "0123456789ABCDEF ";
BIT:= [ $0001, $0002, $0004, $0008, $0010, $0020, $0040, $0080,
$0100, $0200, $0400, $0800, $1000, $2000, $4000, $8000];
TEXT(TV,"-- 68000/68881 DISASSEMBLER, V1.1x3 --
PRESS ^"ESC^" TO RESTART THIS PROGRAM.
PRESS ANY KEY TO DISASSEMBLE A LINE.
");
loop begin
CRLF(TV);
TEXT(TV,"OUTPUT DEVICE (0-7)? ");
DEV:= INTIN(KB);
TEXT(TV,"ADDRESS? $"); \Get start address
PC:= HEXIN(KB);
OPENO(DEV);
BASE:= 0;
loop begin
ASCPTR:= 0; \Initialize line buffer pointers
HEXPTR:= 23;
TXTPTR:= 45;
for II:= 0,TXTPTR-1 do LINEBUF(II):= ^ ; \Init line buffer
LINEPTR:= 12; \Output 32-bit PC value
HEXW(SWAP_W(PC)); \Output high 16 bits
HEXW(PC); \Output low 16 bits
CHARO(^:);
GETOP; \Get word from memory
LOOKUP;
CRO;
\Dump line buffer to output device:
for II:= 0,TXTPTR-1 do CHOUT(DEV,LINEBUF(II));
II:= GETKEY;
case II of
ESC: quit;
$03: exit; \CTRL-C
$10: ABORT \CTRL-P
other; \do the loop
end;
CLOSE(DEV);
end;
end; \MAIN
SC: